home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Toolbox / Visual Basic Toolbox (P.I.E.)(1996).ISO / lang_ext / subcls / readme.txt < prev   
Encoding:
Text File  |  1995-08-24  |  8.9 KB  |  182 lines

  1. README.TXT - Read-me file for SUBCLS.ZIP
  2.  
  3. ------------------------------------------------------------------------
  4. NOTE: Use -d when unzipping SUBCLS.ZIP to have subdirectories recreated.
  5. ------------------------------------------------------------------------
  6.  
  7. Subclassing Examples, Copyright (c) 1995 Jonathan Wood and Karl Peterson
  8. Redistributed by Permission
  9.  
  10.  
  11. INTRODUCTION:
  12. The accompanying files provide several examples of using a subclassing
  13. control with Visual Basic to intercept Windows messages. Emphasis is
  14. placed on those messages that result in functionality that cannot be
  15. obtained through Visual Basic alone.
  16.  
  17. These files include complete source code for an article in the September
  18. 1995 issue of Visual Basic Programmer's Journal (tentatively entitled
  19. "Subclass your way around VB's limitations"). Refer to that article for
  20. additional information on the techniques used. Also included here are
  21. four additional examples not mentioned in the article.
  22.  
  23. In addition, the subclassing control MSGHOOK.VBX is also included.
  24. Although other subclassing controls are available, the examples
  25. presented here are written to work with this control. See MSGHOOK.TXT
  26. for more information regarding the Message Hook custom control.
  27.  
  28. If you'd like to contact the authors of the demo programs and article,
  29. they can be reached on CompuServe in either the VBPJ or MSBASIC forums.
  30. Jonathan Wood at 72134,263 and Karl Peterson at 72302,3707.
  31.  
  32.  
  33. EXAMPLES:
  34. The article contains 8 tips. They are described briefly below and
  35. reference is made to the project that corresponds to the tip. Following
  36. these 8 tips are 4 additional ones. Since these were not covered in the
  37. article, a discussion of them is provided.
  38.  
  39. 1. SHOWING STATUSBAR INFORMATION FOR MENU COMMANDS
  40. Refer to the article and the MENUSEL project.
  41.  
  42. 2. ADDING A COMMAND TO A FORM'S SYSTEM MENU
  43. Refer to the article and the SYSCMD project.
  44.  
  45. 3. SUPPORTING DRAG-AND-DROP FROM FILE MANAGER
  46. Refer to the article and the DROPFILE project.
  47.  
  48. 4. LEFT JUSTIFYING CAPTION TEXT
  49. Refer to the article and the LEFTCAP project.
  50.  
  51. 5. RESTRICTING A WINDOW SIZE RANGE
  52. Refer to the article and the GETMINMX project.
  53.  
  54. 6. PAINTING THE BACKGROUND OF AN MDIFORM
  55. Refer to the article and the MDIPAINT project.
  56.  
  57. 7. DRAWING CUSTOM MENU COMMANDS
  58. Refer to the article and the OWNRDRAW project.
  59.  
  60. 8. HOOKING INTO THE CLIPBOARD VIEWER CHAIN
  61. Refer to the article and the CLIPVIEW project.
  62.  
  63.  
  64. 9. CHANGING MENU TEXT (INITMENU)
  65. Visual Basic allows you to modify the text of a menu command by setting
  66. the Caption property of a menu object. However, it often makes more
  67. sense to be able to set this caption just before the drop down menu is
  68. displayed. For example, let's say you had a spreadsheet with names and,
  69. when a menu was dropped down, you wanted the currently selected name to
  70. appear in the menu as part of a command. Rather than changing the menu
  71. caption every time the current selection changes, wouldn't it be easier
  72. to simply set the caption to the currently selected name just before the
  73. menu is displayed?
  74.  
  75. Visual Basic does allow you to do this. For example, if you have an Edit
  76. menu that contains a Copy command, you can modify the Copy command's
  77. Caption property in the Edit menu's Click event. The Edit menu's Click
  78. event occurs before the menu is displayed. Unfortunately, Windows has
  79. already calculated the width of the menu at this point. If the new text
  80. for the caption is longer that the width of the menu, the text will be
  81. cut off.
  82.  
  83. We can solve this problem by using a subclassing control to intercept
  84. the WM_INITMENUPOPUP message. This message is sent before a drop down
  85. menu is displayed and, significantly, before the width of the menu has
  86. been calculated. The INITMENU project demonstrates this technique.
  87.  
  88. The value you assign to the Result parameter, which MsgHook passes to
  89. the Message event handler, will be returned to Windows. Like the wParam
  90. and lParam paramters, the meaning of the value returned depends on the
  91. actual message being sent. However, most messages, including
  92. WM_MENUSELECT, simply use a return value of 0 to indicate that your
  93. program processed the message.
  94.  
  95.  
  96. 10. DETECTING SYSTEM COLOR CHANGES (SYSCOLOR)
  97. Often when painting custom elements on your forms, you want to use the
  98. default system colors so they will blend in nicely with the appearance
  99. of the rest of the screen. Windows offers the GetSysColor API call to
  100. retrieve any of the colors which the user can set in Control Panel for
  101. items such as buttons, titlebars, borders, and so on. But, what if the
  102. user alters their color preferences while your program is running? For
  103. performance reasons, you may decide that it's best to store the system
  104. colors in an array, so you can draw immediately with them rather than
  105. calling the GetSysColor API repeatedly.
  106.  
  107. Hooking the WM_SYSCOLORCHANGE provides notification whenever the system
  108. colors change.  This message is closely followed with a WM_PAINT message
  109. which will fire the Form_Paint event in your project. By retrieving each
  110. of the system colors during the hooked Message event (see the SYSCOLOR
  111. project), the color array is refreshed prior to the painting. There is
  112. no need to invoke the original window procedure as Visual Basic has never
  113. reacted to this message.
  114.  
  115. One other point of interest is the way the array of colors is initially
  116. filled. Rather than duplicate the looping code, SendMessage is employed
  117. to fire the Message event just set up during the Form_Load event.
  118.  
  119.  
  120. 11. FORCING AN APP TO REMAIN MINIMIZED (MINAPP)
  121. Some applications don't need a windowed user interface. These are
  122. typically written to process large quantities of data in the background,
  123. or to sit idly by monitoring and reacting to system events. If you've
  124. written such an application, you may decide that itÆs best for it to
  125. remain minimized either as an icon or in the Windows 95 taskbar, but
  126. Visual Basic doesn't provide a convenient means of doing so. If a form's
  127. WindowState is reset to Minimized whenever a Form_Resize event occurs,
  128. there's still an ugly flash as the form first restores to Normal or
  129. Maximized.
  130.  
  131. Hooking the WM_QUERYOPEN message (see the MINAPP project) provides a
  132. means for your form to be notified before its state is altered. An
  133. application can notify Windows that the icon may be opened by returning a
  134. non-zero value, or prevent the icon from opening by returning zero. To
  135. implement this technique in Visual Basic, simply return zero in the
  136. Result parameter when the Message event is fired. There is no need to
  137. invoke the original window procedure.
  138.  
  139. One precaution to observe is to not perform any actions which would cause
  140. an activation or alter the focus while processing this message. To
  141. provide some degree of user interaction with your iconized application,
  142. implement the code presented in the SYSCMD project to add one or several
  143. menu options to the form's system menu.
  144.  
  145.  
  146. 12. PREVENTING A WINDOW FROM BEING SIZED OR MOVED (WINPOSCH)
  147. Just before a window gets sized or moved, Windows sends it a
  148. WM_WINDOWPOSCHANGING message that includes information about the new
  149. window position. A window procedure can inspect the information about the
  150. new position and even modify it.
  151.  
  152. The WM_WINDOWPOSCHANGING message uses the lParam parameter to hold the
  153. address of (or pointer to) a WINDOWPOS user-defined type (see the
  154. WINPOSCH project). While Visual Basic doesn't support pointers, the
  155. Windows API provides a function called hmemcpy which can be used to copy
  156. data from one location to another. Using hmemcpy, this example copies the
  157. data from the address specified by lParam to a Visual Basic variable of
  158. type WINDOWPOS. Note that the code declares two hmemcpy parameters As
  159. Any. This is done to provide maximum flexibility but also means that
  160. Visual Basic is not able to verify that the correct data types are sent.
  161. Care should be taken when incorporating hmemcpy in your own applications,
  162. as it can be a little tricky.
  163.  
  164. After using hmemcpy, we end up with a copy of the WINDOWPOS data
  165. structure in a Visual Basic variable. This data structure contains
  166. information about the new window position. If this information is
  167. modified, the changes will affect how the window is moved. Setting the
  168. SWP_NOSIZE and SWP_NOMOVE bits of the flags element of the WINDOWPOS
  169. structure prevents any moving or sizing at all. This example, sets
  170. these bits and then calls hmemcpy once again to copy the data structure
  171. back.
  172.  
  173. This project contain some additional statements to detect if the window
  174. is minimized. If the window is minimized, the program allows the window
  175. to be sized normally. Apparently, when a window gets this message as the
  176. result of a window becoming unminimized, the form's WindowState will
  177. already indicate that the form is not an icon. Therefore, the code also
  178. keeps track of the WindowState for the last time the WM_WINDOWPOSCHANGING
  179. message was received. If you feel like experimenting, you can take these
  180. conditional statements out and see how the form behaves when you minimize
  181. it.
  182.